package com.ld.common.util.notice.service;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.ld.admin.model.system.NoticeActionModel;
import com.ld.common.util.notice.NoticeManager;
import com.ld.common.util.notice.NoticeModel;
import com.ld.shieldsb.common.core.model.Result;
import com.ld.shieldsb.common.core.util.StringUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 发送通知，需要实现发送给用户和群组的方法
 * 
 * @ClassName NoticeSendService
 * @author <a href="mailto:donggongai@126.com" target="_blank">吕凯</a>
 * @date 2019年1月30日 下午1:38:59
 *
 */
@Slf4j
public abstract class NoticeSendService {
    // 报警线程池
    private static final ExecutorService ALARM_EXECUTOR_SERVICE = new ThreadPoolExecutor(3, 5, 60, TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(1000), new ThreadPoolExecutor.CallerRunsPolicy());

    public NoticeSendService() {
        init();
    }

    protected void init() {
    }

    /**
     * 根据类型获取实例
     * 
     * @Title getInstance
     * @author 吕凯
     * @date 2019年1月30日 下午12:37:05
     * @param classes
     * @return NoticeSendService
     */
    public static NoticeSendService getInstance(Class<? extends NoticeSendService> classes) {
        NoticeSendService service = null;
        try {
            service = classes.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            log.error("", e);
        }
        return service;
    }

    /**
     * 发送给用户
     * 
     * @Title sendToUser
     * @author 吕凯
     * @date 2019年1月30日 下午1:39:54
     * @param noticeType
     * @param title
     * @param content
     * @param userId
     * @return String
     */
    public abstract Result sendToUser(String[] noticeTypes, String title, String content, String userId);

    /**
     * 发送给群组
     * 
     * @Title sendToGroup
     * @author 吕凯
     * @date 2019年1月30日 下午1:40:07
     * @param noticeType
     * @param title
     * @param content
     * @param groupId
     * @return String
     */
    public abstract Result sendToGroup(String[] noticeTypes, String title, String content, String groupId);

    /**
     * 发送通知的具体实现
     * 
     * @Title sendNotice
     * @author 吕凯
     * @date 2019年1月30日 下午12:34:39
     * @param title
     * @param content
     * @param noticeType
     * @param sendTo
     *            void
     */
    public static Result sendNotice(String title, String content, String noticeType, String sendTo) {
        Result result = new Result();
        NoticeModel noticeTo = NoticeManager.get(noticeType);
        if (noticeTo != null) {
            if (StringUtils.isBlank(sendTo)) {
                log.warn("接收用户为空！");
            } else {
//                result = noticeTo.notice(null, sendTo, title, content, null);
                try {
                    Future<Result> future = ALARM_EXECUTOR_SERVICE.submit(() -> {
                        Result resultSend = noticeTo.notice(null, sendTo, title, content, null);
                        return resultSend;
                    });
                    result = future.get(3, TimeUnit.SECONDS); // 3秒超时
                } catch (TimeoutException e) { // 超时提示
                    result.setSuccess(true);
                    result.setMessage("发送消息的请求已经提交！");
                } catch (Exception e) {
                    result.setMessage("发送失败，详细信息请联系管理员！");
                    log.error("", e);
                }
            }
        }
        return result;
    }

    /**
     * 发送通知，根据配置信息,发送到的账户需要查询
     * 
     * @Title sendNotice
     * @author 吕凯
     * @date 2019年1月30日 下午12:36:14
     * @param noticActionModel
     * @param content
     *            void
     */
    public Result sendNotice(NoticeActionModel noticActionModel, String content) {
        Result result = new Result();
        String[] types = StringUtils.getStrArr(noticActionModel.getType());
        String[] sendToUsers = StringUtils.getStrArr(noticActionModel.getSendToUser());
        String[] sendToGroups = StringUtils.getStrArr(noticActionModel.getSendToGroup());
        String msg = "";
        int userErrNum = 0;
        int userTotleNum = 0;
        int groupErrNum = 0;
        int groupTotleNum = 0;
        if (types != null && types.length > 0) {
            if (sendToUsers != null && sendToUsers.length > 0) { // 发给用户
                for (String sendToUser : sendToUsers) {
                    userTotleNum++; //
                    result = sendToUser(types, noticActionModel.getTitle(), content, sendToUser);
                    if (!result.getSuccess()) {
                        userErrNum++;
                    }
                }
            }
            if (sendToGroups != null && sendToGroups.length > 0) { // 发给群组
                for (String sendToGroup : sendToGroups) {
                    groupTotleNum++;
                    result = sendToGroup(types, noticActionModel.getTitle(), content, sendToGroup);
                    if (!result.getSuccess()) {
                        groupErrNum++;
                    }
                }
            }
        }
        result.setSuccess(true);
        if (userTotleNum != 0) {
            msg += "共发送给" + userTotleNum + "个用户，其中失败" + userErrNum + "个 ";
        }
        if (groupTotleNum != 0) {
            msg += "共发送给" + groupTotleNum + "个群组，其中失败" + groupErrNum + "个 ";
        }
        if (userErrNum + groupErrNum > 0) {
            result.setSuccess(false);
        }
        result.setMessage(msg);
        return result;
    }

    public void shutdown() {
        ALARM_EXECUTOR_SERVICE.shutdownNow();
    }

}
